package com.hawk.eye.server.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.type.TypeReference;
import com.hawk.eye.framework.core.domain.entity.SysUser;
import com.hawk.eye.common.model.TemplateNode;
import com.hawk.eye.common.utils.*;
import com.hawk.eye.common.page.PageQuery;
import com.hawk.eye.common.page.PageResult;
import com.hawk.eye.framework.utils.CollectionUtil;
import com.hawk.eye.framework.utils.ExceptionUtils;
import com.hawk.eye.framework.utils.PlaceholderUtil;
import com.hawk.eye.server.convert.TemplateConvert;
import com.hawk.eye.server.domain.dto.req.TemplateReqDTO;
import com.hawk.eye.server.domain.dto.resp.TemplateRespDTO;
import com.hawk.eye.server.domain.po.Template;
import com.hawk.eye.server.mapper.SysUserMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import com.hawk.eye.server.mapper.TemplateMapper;
import com.hawk.eye.server.service.ITemplateService;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author salad
 * @date 2023-09-28
 */
@Service
@RequiredArgsConstructor
public class TemplateServiceImpl extends ServiceImpl<TemplateMapper, Template> implements ITemplateService {

    private final TemplateMapper templateMapper;

    private final SysUserMapper userMapper;

    private final PlaceholderUtil PLACEHOLDER_RESOLVER = PlaceholderUtil.getDefaultResolver();


    @Override
    public List<TemplateRespDTO> defaultTemplate() {
        Template template = templateMapper.selectById(1);
        if (template == null || StringUtil.isBlank(template.getOriginalTemplateJson())) {
            return new ArrayList<>();
        }
        return TemplateConvert.INSTANCE.to2(JsonUtil.parse(template.getOriginalTemplateJson(), new TypeReference<List<TemplateNode>>() {
        }));
    }

    @Override
    public List<TemplateRespDTO> templateList() {
        List<TemplateRespDTO> templateList = new ArrayList<>();
        List<Template> templates = templateMapper.selectList(Wrappers.emptyWrapper());
        for (Template item : templates) {
            String templateJson = item.getOriginalTemplateJson();
            if (StringUtil.isBlank(templateJson)) {
                continue;
            }
            List<TemplateNode> nodes = JsonUtil.parse(templateJson, new TypeReference<List<TemplateNode>>() {
            });
            if (CollectionUtil.isNotEmpty(nodes)) {
                //todo sort小心有null值
                nodes = nodes.stream()
                        .sorted(Comparator.comparing(TemplateNode::getSort)).collect(Collectors.toList());
                TemplateRespDTO dto = new TemplateRespDTO();
                dto.setId(item.getId());
                dto.setTemplateName(item.getTemplateName());
                dto.setTemplateNodes(nodes);
                templateList.add(dto);
            }
        }
        return templateList;
    }

    @Override
    public PageResult<TemplateRespDTO> page(PageQuery pageQuery, TemplateReqDTO reqDTO) {
        IPage<TemplateRespDTO> pages = templateMapper.page(pageQuery.toPage(), reqDTO);
        for (TemplateRespDTO record : pages.getRecords()) {
            String templateJson = record.getOriginalTemplateJson();
            if (StringUtil.isNotBlank(templateJson)) {
                List<TemplateNode> templateNodes = JsonUtil.parse(templateJson, new TypeReference<List<TemplateNode>>() {
                });
                record.setTemplateNodes(templateNodes);
            }
        }
        return PageResult.of(pages);
    }

    @Override
    public TemplateRespDTO getTemplate(Long templateId) {
        Template template = templateMapper.selectById(templateId);
        ExceptionUtils.isEmptyThrow(template, "模板[{}]不存在", templateId);
        TemplateRespDTO dto = new TemplateRespDTO();
        List<TemplateNode> templateNodes = JsonUtil.parse(template.getOriginalTemplateJson(), new TypeReference<List<TemplateNode>>() {
        });
        dto.setId(template.getId());
        dto.setTemplateName(template.getTemplateName());
        SysUser sysUser = userMapper.selectUserById(template.getCreateUser());
        dto.setCreateUserName(sysUser.getNickName());
        dto.setCreateTime(template.getCreateTime());
        if (!templateNodes.isEmpty()) {
            templateNodes = templateNodes.stream()
                    .sorted(Comparator.comparing(TemplateNode::getSort)).collect(Collectors.toList());
            dto.setTemplateNodes(templateNodes);
        }
        return dto;
    }

    @Override
    public String resolveTemplate(TemplateRespDTO template, Map<String, Object> alarmLogMap) {
        //模板的解析
        StringBuilder content = new StringBuilder();
        List<TemplateNode> templateNodes = template.getTemplateNodes();
        //解析模版数据
        for (int i = 0; i < templateNodes.size(); i++) {
            if (templateNodes.get(i).getAlarmOut() == null || !templateNodes.get(i).getAlarmOut()) {
                continue;
            }
            String value = PLACEHOLDER_RESOLVER.resolveByMap(templateNodes.get(i).getFieldValue(), alarmLogMap);
            if (value == null) {
                value = "";
            }
            content.append(templateNodes.get(i).getFieldKey()).append(":").append(value);
            if (i < templateNodes.size() - 1) {
                content.append("\n");
            }
        }
        return content.toString();
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public boolean save(TemplateReqDTO reqDTO) {
        return saveOrUpdate(reqDTO);
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public boolean update(TemplateReqDTO reqDTO) {
        ExceptionUtils.isEmptyThrow(reqDTO.getId(), "模板ID不能为空");
        return saveOrUpdate(reqDTO);
    }

    private boolean saveOrUpdate(TemplateReqDTO reqDTO) {
        ExceptionUtils.isEmptyThrow(reqDTO.getTemplateName(), "模板名称不能为空");
        ExceptionUtils.isTrueThrow(CollectionUtil.isEmpty(reqDTO.getTemplateNodes()), "模板字段不能为空");
        long count = count(Wrappers.<Template>lambdaQuery()
                .eq(Template::getTemplateName, reqDTO.getTemplateName())
                .ne(reqDTO.getId() != null, Template::getId, reqDTO.getId()));
        ExceptionUtils.isTrueThrow(count > 0, "模板名称[{}]已存在", reqDTO.getTemplateName());
        List<TemplateNode> templateNodes = reqDTO.getTemplateNodes();
        String json = JsonUtil.toJson(templateNodes);
        ExceptionUtils.isEmptyThrow(json, "模板保存失败，请检查模板配置！");
        Template template = new Template();
        template.setId(reqDTO.getId());
        template.setTemplateName(reqDTO.getTemplateName());
        template.setOriginalTemplateJson(json);
        return saveOrUpdate(template);
    }

    @Override
    public Map<String, Object> filtrationLogMessageByTemplate(TemplateRespDTO template, Map<String, Object> alarmLogAsMap) {
        Map<String, Object> logMessage = new HashMap<>();
        List<TemplateNode> templateNodes = template.getTemplateNodes();
        if (CollectionUtil.isNotEmpty(templateNodes)) {
            for (TemplateNode node : templateNodes) {
                if (node.getFieldValue() == null) {
                    continue;
                }
                String value = PLACEHOLDER_RESOLVER.resolveKey(node.getFieldValue());
                if (alarmLogAsMap.containsKey(value)) {
                    logMessage.put(value, alarmLogAsMap.get(value));
                }
            }
        }
        return logMessage;
    }

}
